﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using NetJsWire.JsonRpcHandler;
using NetJsWire.JsonRpcHandler.Util;
using NetJsWire.Util;
using NetJsWire.Widgets.Config;
using NetJsWire.Widgets.Core;
using NetJsWire.Widgets.Data;
using NetJsWire.Widgets.Renderers.Form;
using NetJsWire.Widgets.Ui.Layout;
using NetJsWire.Widgets.Ui.ToolBar;
using NetJsWire.Widgets.Ui.Tree;
using Newtonsoft.Json;
using Button = NetJsWire.Widgets.Ui.Form.Button;
using CheckBox = NetJsWire.Widgets.Ui.Form.CheckBox;
using ComboBox = NetJsWire.Widgets.Ui.Form.ComboBox;
using DateField = NetJsWire.Widgets.Ui.Form.DateField;
using FieldSet = NetJsWire.Widgets.Ui.Form.FieldSet;
using Formatting = Newtonsoft.Json.Formatting;
using Label = NetJsWire.Widgets.Ui.Basic.Label;
using MenuItem = NetJsWire.Widgets.Ui.ToolBar.MenuItem;
using NumberField = NetJsWire.Widgets.Ui.Form.NumberField;
using Panel = NetJsWire.Widgets.Ui.Layout.Panel;
using TabControl = NetJsWire.Widgets.Ui.Tabs.TabControl;
using TextField = NetJsWire.Widgets.Ui.Form.TextField;

namespace NetJsWire.Widgets.Renderers.Core
{
    internal class Widget : Element
    {
        internal List<string> Events = new List<string>();
        protected string Poll = "";
        protected Dictionary<string, object> StyleProperties = new Dictionary<string, object>();
        private bool _firstRender = true;

        /// <summary>
        ///   Base render class of all widgets.
        /// </summary>
        /// <param name = "baseObject">The UI base object.</param>
        public Widget( object baseObject )
            : base( baseObject )
        {
            if ( baseObject is ClientDocument )
            {
                WebApplication.Instance.ClientDocument = ( ClientDocument ) baseObject;
                ( ( ClientDocument ) baseObject ).Parent = null;
            }
        }

        protected void RemoveStyleProperty( string name )
        {
            if ( StylesNode.Attributes[ name ] != null )
                StylesNode.Attributes.Remove( StylesNode.Attributes[ name ] );

            if ( StyleProperties.ContainsKey( name ) )
                StyleProperties.Remove( name );
        }

        public override void AddEvent( string name, Delegate value )
        {
            Events.Add( name );
        }

        /// <summary>
        ///   The main render routine.
        ///   It takes care of all the rendering process and spits the Control definition in an XML node.
        /// </summary>
        public override void Render()
        {
            if ( !Rendered )
            {
                XmlNode optionsNode = ControlNode[ "options" ];

                if ( Base is IWidgetContainer )
                {
                    if ( !( Base is ClientDocument ) && !( Base is TabControl ) )
                    {
                        SetConstructionProperty( "layout", ( Base as IWidgetContainer ).Layout.ToString().ToLower() );
                    }

                    if ( !string.IsNullOrEmpty( ( Base as IWidgetContainer ).LayoutConfig ) )
                    {
                        SetConstructionProperty( "layoutConfig", ( Base as IWidgetContainer ).LayoutConfig );
                    }
                }

                if ( !( Base is ClientDocument ) && !( Base is FileUploadField ) )
                {
                    SetConstructionProperty( "id", InternalID );

                    #region Comentado

                    //if ( Base is Control && !( Base is Ui.ToolBar.ToolBar ) )
                    //{
                    //    AnchorStyles anchorStyles = Base.Anchor;
                    //    DockStyle dockStyle = Base.Dock;

                    //    if ( BaseParent != null && ( BaseParent is Ui.Window.Window && ( BaseParent as Ui.Window.Window ).Layout == Ui.Layout.LayoutType.Anchor ) || ( BaseParent is Ui.Layout.Panel && ( BaseParent as Ui.Layout.Panel ).Layout == Ui.Layout.LayoutType.Anchor ) )
                    //    {
                    //        if ( ( ( anchorStyles & AnchorStyles.Bottom ) == AnchorStyles.Bottom ) && !( ( anchorStyles & AnchorStyles.Top ) == AnchorStyles.Top ) )
                    //            Base.Top -= 6;

                    //        if ( ( ( anchorStyles & AnchorStyles.Right ) == AnchorStyles.Right ) && !( ( anchorStyles & AnchorStyles.Left ) == AnchorStyles.Left ) )
                    //            Base.Left -= 6;
                    //        else
                    //            Base.Left += 6;
                    //    }

                    //    if ( dockStyle == DockStyle.Fill || dockStyle == DockStyle.Top || dockStyle == DockStyle.Left )
                    //    {
                    //        RemoveStyleProperty( "top" );
                    //        if ( dockStyle == DockStyle.Fill || dockStyle == DockStyle.Top )
                    //        {
                    //            RemoveStyleProperty( "height" );
                    //            SetStyleProperty( "height", "'100%'" );
                    //            RemoveStyleProperty( "width" );
                    //            SetStyleProperty( "width", "'100%'" );
                    //            SetConstructionProperty( "anchor", "100% 100%" );
                    //        }
                    //    }

                    //    if ( dockStyle == DockStyle.Bottom )
                    //    {
                    //        RemoveStyleProperty( "width" );
                    //        SetStyleProperty( "width", "'100%'" );
                    //    }

                    //    if ( !( Base is Ui.Window.Window && ( Base as Ui.Window.Window ).Centered ) && !( dockStyle == DockStyle.Fill ) )
                    //    {

                    //        if ( ( anchorStyles & AnchorStyles.Left ) == AnchorStyles.Left )
                    //            //if (Base is Ui.Form.Button)
                    //            SetStyleProperty( "left", Base.Left );
                    //        //else
                    //        //	SetConstructionProperty("x", ((Control)Base).Left);

                    //        if ( ( anchorStyles & AnchorStyles.Top ) == AnchorStyles.Top )
                    //            //if (Base is Ui.Form.Button)
                    //            SetStyleProperty( "top", Base.Top );
                    //        //else
                    //        //	SetConstructionProperty("y", ((Control)Base).Top);

                    //        if ( ( anchorStyles & AnchorStyles.Right ) == AnchorStyles.Right )
                    //        {
                    //            if ( Base.Parent != null )
                    //            {
                    //                SetStyleProperty( "right", Base.Parent.ClientSize.Width - ( Base.Left + Base.Width ) );
                    //            }
                    //        }

                    //        if ( ( anchorStyles & AnchorStyles.Bottom ) == AnchorStyles.Bottom )
                    //        {

                    //            if ( Base.Parent != null )
                    //            {
                    //                SetStyleProperty( "bottom", Base.Parent.ClientSize.Height - ( Base.Top + Base.Height ) );
                    //            }
                    //        }
                    //    }
                    //}

                    #endregion
                }

                if ( !string.IsNullOrEmpty( Base.ConfigOptions.Anchor ) )
                    SetConstructionProperty( "anchor", Base.ConfigOptions.Anchor );

                if ( Base.ConfigOptions is BoxComponentConfigOptions && Base.ConfigOptions.Margins != null )
                {
                    if ( Base.ConfigOptions.ShouldSerializeMargins() )
                    {
                        SetConstructionProperty( "margins", JsonConvert.SerializeObject( Base.ConfigOptions.Margins ) );
                    }
                }

                if ( Base.ConfigOptions.BaseParams != null && Base.ConfigOptions.BaseParams.Count > 0 )
                    SetConstructionProperty( "baseParams", JsonConvert.SerializeObject( Base.ConfigOptions.BaseParams, Formatting.None, new JsonConverter[] { new BaseParamCollectionJsonConverter() } ) );

                if ( Base.ConfigOptions.Tools != null && Base.ConfigOptions.Tools.Count > 0 )
                {
                    var tools = new ToolConfig[ Base.ConfigOptions.Tools.Count ];
                    Base.ConfigOptions.Tools.CopyTo( tools );
                    foreach ( var toolConfig in tools.Where( toolConfig => toolConfig.Handler.Contains( "{0}" ) || toolConfig.Handler.Contains( "{1}" ) ) )
                    {
                        if ( BaseParent is IWidget )
                            toolConfig.Handler = toolConfig.Handler.Replace( "{0}", GetCmp ).Replace( "{1}", ( ( IWidget ) BaseParent ).Renderer.GetCmp );
                        else
                            toolConfig.Handler = toolConfig.Handler.Replace( "{0}", GetCmp );
                    }
                    SetConstructionProperty( "tools", JsonConvert.SerializeObject( tools ) );
                }

                if ( Base.ConfigOptions.Listeners != null && Base.ConfigOptions.Listeners.Count > 0 )
                {
                    SetConstructionProperty( "listeners", JsonConvert.SerializeObject( Base.ConfigOptions.Listeners, Formatting.None, new JsonConverter[] { new ListenerCollectionJsonConverter(), new ListenerJsonConverter() } ) );
                }


                if ( ConstructionProperties.Count > 0 )
                {
                    foreach ( var cProp in ConstructionProperties )
                    {
                        if ( !( cProp.Value is bool ) && !ReservedWords.Contains( cProp.Key ) )
                        {
                            SetAttribute( optionsNode, cProp.Key, JsonConvert.ToString( cProp.Value ) ); //.Replace( "[", "" ).Replace( "]", "" ) );
                        }
                        else
                        {
                            SetAttribute( optionsNode, cProp.Key, cProp.Value );
                        }
                    }
                    ConstructionProperties.Clear();
                }

                if ( Plugins != null && Plugins.Count > 0 )
                {
                    SetAttribute( optionsNode, "plugins", JsonConvert.SerializeObject( Plugins, Formatting.None, new JsonConverter[] { new NotQuotedJsonStringConverter() } ) );
                }

                SetAttribute( ControlNode, "name", ClientID );
                SetAttribute( ControlNode, "parent", ClientParentToRender );
                ControlNode.Attributes.Append( WebApplication.Instance.XmlDocument.CreateAttribute( "type" ) );
                if ( Base is ClientDocument )
                {
                    SetAttribute( "isContainer", true );

                    SetAttribute( ControlNode, "type", "Ext.Viewport" );
                    SetAttribute( optionsNode, "layout",
                                  string.Format( "'{0}'", Base.Layout.ToString().ToLower() ) );
                }
                else
                    SetAttribute( ControlNode, "type", ClassName );

                if ( Base is Control )
                {
                    SetAttribute( ControlNode, "y", Base.Top );
                    SetAttribute( ControlNode, "x", Base.Left );

                    if ( !( Base is Ui.Window.Window ) )
                    {
                        // Form layout containers have trouble dealing with explicit coordinates
                        if ( BaseParent != null && BaseParent is IWidgetContainer )
                        {
                            var bpLayout = ( BaseParent as IWidgetContainer ).Layout;

                            if ( bpLayout == LayoutType.Absolute || bpLayout == LayoutType.Anchor )
                            {
                                if ( bpLayout != LayoutType.Form )
                                {
                                    if ( BaseParent is FieldSet )
                                    {
                                        SetAttribute( optionsNode, "y", Base.Top - 16 );
                                    }
                                    else
                                    {
                                        SetAttribute( optionsNode, "y", Base.Top );
                                    }
                                }
                                if ( bpLayout != LayoutType.Form )
                                {
                                    SetAttribute( optionsNode, "x", Base.Left );
                                }
                            }

                            if ( bpLayout != LayoutType.Fit )
                            {
                                if ( !Base.ConfigOptions.AutoWidth )
                                {
                                    if ( optionsNode.Attributes[ "width" ] != null && string.IsNullOrEmpty( optionsNode.Attributes[ "width" ].Value ) )
                                    {
                                        optionsNode.Attributes.Remove( optionsNode.Attributes[ "width" ] );
                                    }
                                    else
                                    {
                                        SetAttribute( optionsNode, "width", Base.Width );
                                    }
                                }
                                else
                                {
                                    if ( bpLayout == LayoutType.Hbox )
                                    {
                                        SetAttribute( optionsNode, "width", string.Empty );
                                        if ( optionsNode.Attributes[ "autoWidth" ] != null )
                                        {
                                            optionsNode.Attributes.Remove( optionsNode.Attributes[ "autoWidth" ] );
                                        }
                                    }
                                }

                                if ( !Base.ConfigOptions.AutoHeight )
                                {
                                    if ( Base is FieldSet )
                                    {
                                        if ( optionsNode.Attributes[ "height" ] == null ) SetAttribute( optionsNode, "height", Base.Height + 16 );
                                    }
                                    else
                                    {
                                        if ( optionsNode.Attributes[ "height" ] == null && !( Base is NumberField || Base is TextField || Base is DateField || Base is ComboBox ) )
                                            SetAttribute( optionsNode, "height", Base.Height );
                                        else if ( Base is TextField && Base.Multiline )
                                            SetAttribute( optionsNode, "height", Base.Height );
                                    }
                                }
                                else
                                {
                                    if ( bpLayout == LayoutType.Vbox )
                                    {
                                        SetAttribute( optionsNode, "height", string.Empty );
                                        if ( optionsNode.Attributes[ "autoHeight" ] != null )
                                        {
                                            optionsNode.Attributes.Remove( optionsNode.Attributes[ "autoHeight" ] );
                                        }
                                    }
                                }

                                if ( optionsNode.Attributes[ "height" ] != null && string.IsNullOrEmpty( optionsNode.Attributes[ "height" ].Value ) )
                                {
                                    optionsNode.Attributes.Remove( optionsNode.Attributes[ "height" ] );
                                }
                            }
                        }
                    }
                    else
                    {
                        SetAttribute( optionsNode, "width", Base.Width );
                        SetAttribute( optionsNode, "height", Base.Height );
                    }
                }
                foreach ( var stProp in StyleProperties.Where( stProp => stProp.Key != "top" && stProp.Key != "left" ) )
                {
                    SetAttribute( StylesNode, stProp.Key, JsonConvert.ToString( stProp.Value ) );
                }
                StyleProperties.Clear();

                SetAttribute( ControlNode, "render", true );
                Rendered = true;
                if ( !( Base is Ui.Window.Window ) && !( Base is ClientDocument ) && !( Base is MenuSeparator ) && Base.GenerateClientMember )
                {
                    // We set it  as null so it can be obtained again because it was set before the name
                    if ( ClientID.EndsWith( "." ) )
                        ClientID = null;
                    if ( !string.IsNullOrWhiteSpace( ClientID ) )
                        WebApplication.Instance.AddChange( ClientID + "=" + GetCmp + ";" );
                    else
                        WebApplication.Instance.AddChange( InternalID + "=" + GetCmp + ";" );
                }

                if ( Base is ITopLevelContainer )
                {
                    AddApplicationTailCommand( "doLayout", true );
                }
            }
            foreach ( var var in Properties )
            {
                var propertyNode = ControlNode[ "propertys" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "property", "" ) );
                SetAttribute( propertyNode, "name", var.Key );
                SetAttribute( propertyNode, "value", JsonConvert.ToString( var.Value ) );
            }
            Properties.Clear();

            foreach ( var var in EqualProperties )
            {
                var equalPropertyNode = ControlNode[ "equalpropertys" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "equalproperty", "" ) );
                SetAttribute( equalPropertyNode, "name", var.Key );
                SetAttribute( equalPropertyNode, "value", JsonConvert.ToString( var.Value ) );
            }
            EqualProperties.Clear();
            if ( !EventsAdded )
                foreach ( EventInfo ei in Base.GetType().GetEvents( BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic ) )
                {
                    var evt = ei.Name;
                    if ( evt == "ClientKeyPress" )
                    {
                        var fi = ClientUtils.FindEventInType( Base.GetType(), ei.Name );
                        if ( fi != null )
                        {
                            var eventDelegates = ( MulticastDelegate ) fi.GetValue( Base );
                            if ( eventDelegates != null )
                            {
                                var methodRender = string.Empty;
                                try
                                {
                                    methodRender =
                                        GetType().GetField( "_" + ei.Name.ToUpper(),
                                                            BindingFlags.Public | BindingFlags.Instance |
                                                            BindingFlags.NonPublic ).GetValue( this ).ToString();
                                }
                                catch ( ArgumentNullException )
                                {
                                }
                                catch ( TargetException )
                                {
                                }
                                catch ( NotSupportedException )
                                {
                                }
                                catch ( FieldAccessException )
                                {
                                }
                                catch ( ArgumentException )
                                {
                                }
                                if ( !Events.Contains( "ClientKeyPress" ) )
                                {
                                    if ( !string.IsNullOrEmpty( methodRender ) )
                                    {
                                        var eventNode =
                                            ControlNode[ "events" ].AppendChild(
                                                WebApplication.Instance.XmlDocument.CreateNode( "element", "event", "" ) );
                                        SetAttribute( eventNode, "name", "keypress" );
                                        eventNode.InnerXml = string.Format( methodRender, InternalID, InternalID );
                                    }
                                    Events.Add( "ClientKeyPress" );
                                }
                            }
                        }
                    }
                    else if ( !Events.Contains( evt ) ) // add it
                    {
                        FieldInfo fi = ClientUtils.FindEventInType( Base.GetType(), ei.Name );
                        if ( fi != null )
                        {
                            var eventDelegates = ( MulticastDelegate ) fi.GetValue( Base );
                            if ( eventDelegates != null )
                            {
                                //eventNode.Attributes.Append( WebApplication.Instance.XmlDocument.CreateAttribute( "name" ) ).Value = ei.Name;
                                var methodRender = string.Empty;
                                var clientName = ei.Name;
                                try
                                {
                                    var clientNameField = GetType().GetField( "_" + ei.Name.ToUpper() + "_CLIENT_NAME",
                                                            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static );
                                    if ( clientNameField != null )
                                    {
                                        var o = clientNameField.GetValue( this );
                                        if ( o != null )
                                        {
                                            clientName = o.ToString();
                                        }
                                    }
                                }
                                catch
                                {
                                    clientName = ei.Name;
                                }
                                try
                                {
                                    var methodRenderField = GetType().GetField( "_" + ei.Name.ToUpper(),
                                                            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static );

                                    if ( methodRenderField != null )
                                    {
                                        var o = methodRenderField.GetValue( this );

                                        if ( o != null )
                                        {
                                            methodRender = o.ToString();
                                        }
                                    }
                                }
                                catch ( ArgumentNullException )
                                {
                                }
                                catch ( TargetException )
                                {
                                }
                                catch ( NotSupportedException )
                                {
                                }
                                catch ( FieldAccessException )
                                {
                                }
                                catch ( ArgumentException )
                                {
                                }
                                XmlNode eventNode;
                                switch ( clientName )
                                {
                                    case "rowselect":
                                    case "cellselect":
                                        eventNode = ControlNode[ "selectionModel" ][ "events" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "event", "" ) );
                                        break;
                                    case "hiddenchange":
                                        eventNode = ControlNode[ "columns" ][ "events" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "event", "" ) );
                                        break;
                                    default:
                                        eventNode = ControlNode[ "events" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "event", "" ) );
                                        break;
                                }
                                SetAttribute( eventNode, "name", clientName );

                                if ( !string.IsNullOrEmpty( methodRender ) )
                                {
                                    if ( Base is Ui.Window.Window || Base is CheckBox || Base is Button ||
                                         Base is TextField || Base is TreePanel || Base is Panel ||
                                         Base is ComboBox || Base is Ui.ToolBar.Button ||
                                         Base is MenuItem ||
                                         Base is ColorMenu || Base is Ui.Table.Table )
                                    {
                                        eventNode.InnerXml = string.Format( methodRender, ClientID, InternalID );
                                    }
                                    else
                                    {
                                        eventNode.InnerXml = string.Format( methodRender, InternalID );
                                    }
                                }
                                else
                                {
                                    eventNode.ParentNode.RemoveChild( eventNode );
                                }
                                Events.Add( ei.Name );
                            }
                        }
                    }
                }

            foreach ( var clientEvent in ClientEvents )
            {
                var clientName = clientEvent.Key;
                XmlNode eventNode = ControlNode[ "events" ];
                var found = false;
                var eventFunc = clientEvent.Value;

                if ( eventNode.HasChildNodes )
                {
                    foreach ( var node in eventNode.ChildNodes.Cast<XmlNode>().Where( node => node.Attributes[ "name" ].Value == clientName ) )
                    {
                        found = true;
                        eventFunc = "[" + node.InnerXml + "," + clientEvent.Value + "]";
                        eventNode = node;
                        break;
                    }
                }

                if ( !found )
                {
                    switch ( clientName )
                    {
                        case "rowselect":
                        case "cellselect":
                            eventNode = ControlNode[ "selectionModel" ][ "events" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "event", "" ) );
                            break;
                        case "hiddenchange":
                            eventNode = ControlNode[ "columns" ][ "events" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "event", "" ) );
                            break;
                        default:
                            eventNode = ControlNode[ "events" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "event", "" ) );
                            break;
                    }

                    SetAttribute( eventNode, "name", clientName );
                }

                eventNode.InnerXml = eventFunc;
            }
            ClientEvents.Clear();

            foreach ( var keyNav in KeyNavs )
            {
                if ( Base is Ui.Window.Window || Base is TextField || Base is Button ||
                     Base is Panel || Base is BorderLayout || Base is CheckBox ||
                     Base is TreePanel || Base is ComboBox || Base is DropDownButton ||
                     Base is MenuItem || Base is Ui.ToolBar.Button || Base is Ui.ToolBar.ToolBar ||
                     Base is Label || Base is FieldSet || Base is Ui.Table.Table )
                {
                    AddApplicationTailDirectCommand( "var _kNav_ = new Ext.KeyMap",
                                                     string.Format( "'{0}', {{key:{1}, fn:{2}, scope:{3}}}", InternalID,
                                                                    keyNav.Key, keyNav.Value, GetCmp ) );
                }
                else
                {
                    AddApplicationTailDirectCommand( "var _kNav_ = new Ext.KeyMap",
                                                     string.Format( "'{0}', {{key:{1}, fn:{2}, scope:{3}}}", InternalID,
                                                                    keyNav.Key, keyNav.Value, GetCmp ) );
                }
            }
            KeyNavs.Clear();

            foreach ( var dCmd in DirectCommands )
            {
                var nodeCommand = WebApplication.Instance.XmlDocument[ "class" ][ "code" ].AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "codeline", "" ) );
                nodeCommand.InnerText = string.Format( "{0} {1};", dCmd.Key, ( ( dCmd.Value != null ) ? dCmd.Value.ToString() : "" ) );
            }
            DirectCommands.Clear();

            foreach ( var cmd in Commands )
            {
                var val = JsonConvert.SerializeObject( cmd, Formatting.None, new CommandConverter() );

                if ( val.StartsWith( "[" ) )
                {
                    val = val.Substring( 1 );
                }
                if ( val.EndsWith( "]" ) )
                {
                    val = val.Substring( 0, val.Length - 1 );
                }

                var codeLineNode = GetTopLevelContainer( this ).ControlNode[ "code" ].AppendChild( ControlNode.OwnerDocument.CreateNode( "element", "codeline", "" ) );

                if ( Base is Ui.Window.Window || Base is TextField || Base is DateField ||
                     Base is Button || Base is Panel || Base is BorderLayout ||
                     Base is CheckBox || Base is TreePanel || Base is ComboBox ||
                     Base is DropDownButton || Base is MenuItem || Base is Ui.ToolBar.Button ||
                     Base is Ui.ToolBar.ToolBar || Base is Label || Base is FieldSet ||
                     Base is Ui.Table.Table || Base is TabControl || Base is ClientDocument )
                {
                    codeLineNode.InnerText = string.Format( "{0}.{1}({2});",
                                                            ( ( Base is ClientDocument || Base is Ui.Window.Window )
                                                                  ? ClientID
                                                                  : GetCmp ), cmd.Key, val );
                }
                else
                {
                    codeLineNode.InnerText = string.Format( "{0}.{1}({2});", GetCmp, cmd.Key, val );
                }
            }
            Commands.Clear();

            foreach ( var cmd in PreCodeCommands )
            {
                string val = null;
                if ( cmd.Value != null )
                {
                    val = JsonConvert.ToString( cmd.Value );
                    //val = val.Substring( 0, val.Length - 1 );
                }
                WebApplication.Instance.AddPreCodeChange( string.Format( "{0}.{1}({2});",
                                                    ( ( Base is ClientDocument )
                                                    ? ClientID
                                                    : GetCmp
                                                    ), cmd.Key, val ) );
            }
            PreCodeCommands.Clear();


            WebApplication.Instance.HasChanges = true;
            ControlNode = null;
            if ( _firstRender )
            {
                OnAfterRender();
                _firstRender = false;
            }
        }
    }
}